package com.baitu.websokettest.ws;

import com.baitu.websokettest.config.WebSocketServerConfigurator;
import com.baitu.websokettest.controller.WebStaticController;
import com.baitu.websokettest.entity.Message;
import com.baitu.websokettest.entity.User;
import com.baitu.websokettest.service.MessageService;
import com.baitu.websokettest.service.impl.MessageServiceImpl;
import com.baitu.websokettest.util.MessageUtils;
import com.baitu.websokettest.util.OlineUser;
import com.google.gson.Gson;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;

@ServerEndpoint(value = "/userchat", configurator =WebSocketServerConfigurator.class)
@Component
@CrossOrigin
public class UserChar {
    public static MessageService messageService;

    private static Gson gson = new Gson();
    private User selfuser;
    private Session session;
    private HttpSession httpSession;

    // 打开连接触发事件
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) throws IOException {
        this.session = session;

        this.httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        // 从httpsession中获取用户对象
        User user = (User) httpSession.getAttribute("user");
        selfuser=user;
        OlineUser.map.put(user.getId(), this);
        // 把当前对象存在容器中
//        将当前在线用户推给所有客户端;
        String message = MessageUtils.getMessage(true, null, zhuan());
        sendAll(message);
    }

    public Set<User> zhuan(){
        Set<User> set=new HashSet<>();
        for(Integer mapkey:OlineUser.map.keySet()){
            set.add(OlineUser.map.get(mapkey).selfuser);
        }
        return set;
    }

    // 收到消息触发事件
    @OnMessage
    public void onMessage(String message, Session session) throws IOException, InterruptedException {
      try {
          System.out.println(message);
          //将message转换成message对象
          Message mess = gson.fromJson(message,Message.class);
          //数据库保存
          System.out.println(mess);
          messageService.save(mess);

          //缓存保存
          if (!mess.isSystem()){
              List<Message> attribute = (List<Message>) httpSession.getAttribute(mess.getToId()+"");
              if (Objects.isNull(attribute)){
                  List<Message> messageList=new ArrayList<>();
                  messageList.add(mess);
                  httpSession.setAttribute(mess.getToId()+"",messageList);
              }else{
                  attribute.add(mess);
              }
              //对方缓存保存
              UserChar userChar = OlineUser.map.get(mess.getToId());
              if(!Objects.isNull(userChar)){
                  List<Message> toAttribute = (List<Message>) userChar.httpSession.getAttribute(mess.getFromId()+"");
                  if (Objects.isNull(toAttribute)){
                      List<Message> messageList=new ArrayList<>();
                      messageList.add(mess);
                      httpSession.setAttribute(mess.getFromId()+"",messageList);
                  }else{
                      toAttribute.add(mess);
                  }
              }
              send(mess);
          }else{
              sendAll(message);
          }
      }catch (Exception e){
          e.printStackTrace();
      }
    }

    // 关闭连接触发事件
    @OnClose
    public void onClose(Session session, CloseReason closeReason) throws IOException {
        User user = (User) httpSession.getAttribute("user");
        OlineUser.map.remove(user.getId());
        String message = MessageUtils.getMessage(true, null, zhuan());
        sendAll(message);

    }

    public void send(Message message) throws IOException {
        UserChar userChar = OlineUser.map.get(message.getToId());
        if (!Objects.isNull(userChar)){
            String result= gson.toJson(message);
            userChar.session.getBasicRemote().sendText(result);
        }
    }

    public void sendAll(String message) throws IOException {
        for (Integer user : OlineUser.map.keySet()) {
            try {
                UserChar userChar=OlineUser.map.get(user);
                userChar.session.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
